﻿using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraEditors;
using System.Data.SqlClient;
using System.ServiceModel;
using System.ServiceModel.Description;
using DM4;
using sscore;
using System.Windows.Forms;
using System.IO;

using System.ServiceModel.Web;
using System.Data.Services;
using System.Data.EntityClient;

namespace DM4Client
{
    public partial class FrmLogin : XtraForm
    {
        private bool _builtInServer;
        private String _workDir;
        private String _cacheDir;
        private String _logDir;
        private String _daemonsDir;
        private String _modulesDir;
        private String _scriptsDir;
        private String _settingsDir;
        private String _assembliesDir;

        private FrmMain _mainfrom;

        private void StartupServer()
        {
            try
            {
                if (FrmMain.Server != null) return;

                _workDir = tbHome.Text;

                _logDir = String.Format("{0}\\{1}", _workDir, "log");
                _cacheDir = String.Format("{0}\\{1}", _workDir, "cache");
                _daemonsDir = String.Format("{0}\\{1}", _workDir, "daemons");
                _modulesDir = String.Format("{0}\\{1}", _workDir, "modules");
                _scriptsDir = String.Format("{0}\\{1}", _workDir, "scripts");
                _settingsDir = String.Format("{0}\\{1}", _workDir, "settings");
                _assembliesDir = _workDir;

                if (FrmMain.ServerLog != null) FrmMain.ServerLog.Close();
                FrmMain.ServerLog = Log.CreateLogWithoutDataset(String.Format("{0}\\{1}", tbHome.Text, "dm4.log"),
                                                             EncodingType.Utf8, LogMode.Full, false);                
                FrmMain.WriteServerLog("Begin start DM4 service...");

                string paramsFileName = String.Format("{0}\\{1}", tbHome.Text, "dm4config.xml");
                FrmMain.WriteServerLog(String.Format("Config file: {0}", paramsFileName));

                FrmMain.ServerParams = Params.CreateNonCryptedParamsWithoutEtalon(paramsFileName);
                FrmMain.WriteServerLog("Load parameters...");

                if (FrmMain.ServerParams.GetBooleanParam("UseDatabase"))
                {
                    FrmMain.WriteServerLog("Check database connection...");
                    FrmMain.ServerDBConnection = new SqlConnection(FrmMain.ServerParams.GetStringParam("ConnectionString"));
                    FrmMain.ServerDBConnection.Open();
                    FrmMain.WriteServerLog("DB connection test successfully");
                }

                //set current directories
                FrmMain.ServerParams.SetStringParam(DM4Consts.DaemonsDir, _daemonsDir);
                FrmMain.ServerParams.SetStringParam(DM4Consts.ModulesDir, _modulesDir);
                FrmMain.ServerParams.SetStringParam(DM4Consts.ScriptsDir, _scriptsDir);
                FrmMain.ServerParams.SetStringParam(DM4Consts.SettingsDir, _settingsDir);
                FrmMain.ServerParams.SetStringParam(DM4Consts.LogDir, _logDir);
                FrmMain.ServerParams.SetStringParam(DM4Consts.WorkDir, _workDir);
                FrmMain.ServerParams.SetStringParam(DM4Consts.AssembliesDir, _assembliesDir);

                FrmMain.ServerParams.SetStringParam("ListenerAddress", "http://127.0.0.1:8000/DM4");
                FrmMain.ServerParams.SetDateTimeParam("StartTime", DateTime.Now);
                FrmMain.ServerParams.Save();

                DirectoryInfo directory = new DirectoryInfo(_logDir);
                if (!directory.Exists) directory.Create();

                directory = new DirectoryInfo(_cacheDir);
                if (!directory.Exists) directory.Create();
                else
                {
                    directory.Delete(true);
                    directory.Create();
                }

                directory = new DirectoryInfo(_daemonsDir);
                if (!directory.Exists) directory.Create();

                directory = new DirectoryInfo(_modulesDir);
                if (!directory.Exists) directory.Create();

                directory = new DirectoryInfo(_scriptsDir);
                if (!directory.Exists) directory.Create();

                directory = new DirectoryInfo(_settingsDir);
                if (!directory.Exists) directory.Create();

                directory = new DirectoryInfo(_assembliesDir);
                if (!directory.Exists) directory.Create();


                FrmMain.Server = new DM4.DM4(FrmMain.ServerLog, FrmMain.ServerParams, FrmMain.ServerDBConnection, true);

#region по идее эти строки не нужны, т.к. интерфейсные ф-ции достаются через обьект класа
                //FrmMain.WriteServerLog(String.Format("Open listener at address [{0}]...", FrmMain.ServerParams.GetStringParam("ListenerAddress")));

                //Uri uri = new Uri(FrmMain.ServerParams.GetStringParam("ListenerAddress"));
                //FrmMain.WriteServerLog("Uri = " + uri);

                //FrmMain.ServerHost = new ServiceHost(FrmMain.Server, uri);
                //FrmMain.ServerHost.AddServiceEndpoint(typeof(IDM4), new BasicHttpBinding(), "");

                //ServiceMetadataBehavior behavior = new ServiceMetadataBehavior { HttpGetEnabled = true };
                //FrmMain.ServerHost.Description.Behaviors.Add(behavior);
                //FrmMain.ServerHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

                //FrmMain.ServerHost.Open();

                //FrmMain.WriteServerLog("Listener opened successfully");
#endregion по идее эти строки не нужны, т.к. интерфейсные ф-ции достаются через обьект класа
                FrmMain.LogDataClasses = new LogDataClassesDataContext(FrmMain.ServerDBConnection.ConnectionString);
                
                FrmMain.WriteServerLog("DM4 service start successfully!");
            }
            catch (Exception ex)
            {
                FrmMain.WriteServerLog(ex.Message, MessageType.Error);
                throw;
            }
        }

        private void DoLogin()
        {
            try
            {
                lblWait.Visible = true;
                lblMessage.Visible = false;
                Enabled = false;
                                
                if (_builtInServer)
                    StartupServer();

                bool res = FrmMain.CreateServerChannel(FrmMain.Srvnames[cbServer.Text], _builtInServer);
                if (!res) return;
                
                try
                {
                    XMLInfo xi = FrmMain.Dm4Srv.Login(tbUser.Text, tbPassword.Text);

                    if (xi.OperResult.Result == DM4Consts.ErrorServerLoading || xi.OperResult.Result == DM4Consts.ErrorServerShutdown)
                    {
                        lblMessage.Text = xi.OperResult.Message;
                        lblMessage.Visible = true;
                        return;
                    }

                    FrmMain.CurrentUser = XMLInfo.FillTable(xi);

                    if (FrmMain.CurrentUser.Rows.Count == 0)
                        throw new Exception("Login or password are incorrect!");

                    DialogResult = DialogResult.OK;
                    Close();

                    if (_mainfrom != null) _mainfrom.SetActiveTab();
                }
                catch (EndpointNotFoundException ex)
                {
                    FrmMain.WriteError(ex.Message);
                    MessageBox.Show("Unable to connect with service.", MessageType.Error.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (Exception ex)
                {
                    FrmMain.WriteError(ex.Message);
                    MessageBox.Show(ex.Message, MessageType.Error.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            finally
            {
                lblWait.Visible = false;
                Enabled = true;
            }
        }

        public FrmLogin(FrmMain mainfrom = null)
        {
            InitializeComponent();
            _mainfrom = mainfrom;
        }

        private void btnOkClick(object sender, EventArgs e)
        {
            DoLogin();
        }

        private void CheckBuiltInServer()
        {
            _builtInServer = cbServer.Text.Contains("Built-in");
            tbHome.Visible = _builtInServer;
            lblServerHome.Visible = _builtInServer;
        }

        private void FrmLoginShown(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(tbUser.Text))
                tbPassword.Focus();
            else
                tbUser.Focus();

            CheckBuiltInServer();
        }

        private void cbServerSelectedIndexChanged(object sender, EventArgs e)
        {
            CheckBuiltInServer();
        }

        private void tbPasswordKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
                DoLogin();
            e.Handled = true;
        }

        private void tbHomeButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            if (fbHome.ShowDialog() == DialogResult.OK)
                tbHome.Text = fbHome.SelectedPath;
        }
    }
}
